home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / util / setcpu16 / part02 < prev    next >
Encoding:
Text File  |  1990-08-14  |  41.6 KB  |  1,281 lines

  1. Newsgroups: comp.sources.amiga
  2. Path: abcfd20.larc.nasa.gov!amiga-request
  3. From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  4. Subject: v90i222: SetCPU 1.60 - identify and adjust parameters based on cpu type, Part02/04
  5. Message-ID: <comp.sources.amiga:v90i222@abcfd20.larc.nasa.gov>
  6. Sender: tadguy@abcfd20.larc.nasa.gov (Tad Guy)
  7. Reply-To: daveh@cbmvax.commodore.com (Dave Haynie)
  8. X-Post-Discussions-To: comp.sys.amiga
  9. Organization: NASA Langley Research Center, Hampton, VA  USA
  10. Date: 14 Aug 90 21:38:23 GMT
  11. Approved: tadguy@abcfd01.larc.nasa.gov (Tad Guy)
  12. X-Mail-Submissions-To: amiga@uunet.uu.net
  13.  
  14. Submitted-by: daveh@cbmvax.commodore.com (Dave Haynie)
  15. Posting-number: Volume 90, Issue 222
  16. Archive-name: util/setcpu-1.60/part02
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 2 (of 4)."
  25. # Contents:  SetCPU.h coolhand.c memory.c mmu.c
  26. # Wrapped by tadguy@abcfd20 on Tue Aug 14 17:35:35 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'SetCPU.h' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'SetCPU.h'\"
  30. else
  31. echo shar: Extracting \"'SetCPU.h'\" \(10417 characters\)
  32. sed "s/^X//" >'SetCPU.h' <<'END_OF_FILE'
  33. X/*
  34. X    SetCPU V1.60
  35. X    by Dave Haynie, April 13, 1990
  36. X    Released to the Public Domain
  37. X
  38. X    HEADER FILE
  39. X*/
  40. X
  41. X
  42. X#define PROGRAM_VERSION    160
  43. X
  44. X#include <exec/types.h>
  45. X#include <exec/execbase.h>
  46. X#include <exec/nodes.h>
  47. X#include <exec/lists.h>
  48. X#include <exec/memory.h>
  49. X#include <exec/io.h>
  50. X#include <devices/trackdisk.h>
  51. X#include <libraries/expansionbase.h>
  52. X#include <libraries/configregs.h>
  53. X#include <libraries/configvars.h>
  54. X#include <graphics/gfxbase.h>
  55. X#include <graphics/gfxmacros.h>
  56. X#include <intuition/intuition.h>
  57. X#include <intuition/intuitionbase.h>
  58. X#include <libraries/dosextens.h>
  59. X#include <libraries/filehandler.h>
  60. X#include <functions.h>
  61. X#include <stdio.h>
  62. X#include <ctype.h>
  63. X
  64. X/* ====================================================================== */
  65. X
  66. X/* Define all bit components used for manipulation of the Cache Control
  67. X   Register. */
  68. X
  69. X#define CACR_INST    ((ULONG)(1L<<0))
  70. X#define CACR_DATA    ((ULONG)(1L<<8))
  71. X#define CACR_FIXED    ((ULONG)(CACR_DATA<<CACR_WALLOC))
  72. X
  73. X#define CACR_WALLOC    5
  74. X#define CACR_BURST    4
  75. X#define CACR_CLEAR    3
  76. X#define CACR_ENTRY    2
  77. X#define CACR_FREEZE    1
  78. X#define CACR_ENABLE    0
  79. X
  80. X#define CACR_ENABLE40    15
  81. X#define CACR_DATA40    16
  82. X
  83. X/* ====================================================================== */
  84. X
  85. X/* Define important bits used in various MMU registers. */
  86. X
  87. X/* Here are the CRP definitions.  The CRP register is 64 bits long, but
  88. X   only the first 32 bits are control bits, the next 32 bits provide the
  89. X   base address of the table. */
  90. X
  91. X#define    CRP_UPPER    (1L<<31)        /* Upper/lower limit mode */
  92. X#define CRP_LIMIT(x)    ((ULONG)((x)&0x7fff)<<16)/* Upper/lower limit value */
  93. X#define CRP_SG        (1L<<9)            /* Indicates shared space */
  94. X#define CRP_DT_INVALID    0x00            /* Invalid root descriptor */
  95. X#define    CRP_DT_PAGE    0x01            /* Fixed offset, auto-genned */
  96. X#define CRP_DT_V4BYTE    0x02            /* Short root descriptor */
  97. X#define    CRP_DT_V8BYTE    0x03            /* Long root descriptor */
  98. X
  99. X/* Here are the TC definitions.  The TC register is 32 bits long. */
  100. X
  101. X#define    TC_ENB        (1L<<31)        /* Enable the MMU */
  102. X#define    TC_SRE        (1L<<25)        /* For separate Supervisor */
  103. X#define    TC_FCL        (1L<<24)        /* Use function codes? */
  104. X#define    TC_PS(x)    ((ULONG)((x)&0x0f)<<20)    /* Page size */
  105. X#define TC_IS(x)    ((ULONG)((x)&0x0f)<<16)    /* Logical shift */
  106. X#define    TC_TIA(x)    ((ULONG)((x)&0x0f)<<12)    /* Table indices */
  107. X#define    TC_TIB(x)    ((ULONG)((x)&0x0f)<<8)
  108. X#define TC_TIC(x)    ((ULONG)((x)&0x0f)<<4)
  109. X#define    TC_TID(x)    ((ULONG)((x)&0x0f)<<0)
  110. X
  111. X/* Here are the page descriptor definitions, for short desctriptors only,
  112. X   since that's all I'm using at this point. */
  113. X   
  114. X#define    PD_ADDR(x)    ((ULONG)(x)&~0x0fL)    /* Translated Address */
  115. X#define IV_ADDR(x)    ((ULONG)(x)&~0x03L)    /* Invalid unused field */    
  116. X#define    PD_WP        (1L<<2)            /* Write protect it! */
  117. X#define PD_CI        (1L<<6)            /* Cache inhibit */
  118. X#define PD_DT_TYPE    0x03            /* Page descriptor type */
  119. X#define PD_DT_INVALID    0x00            /* Invalid root descriptor */
  120. X#define    PD_DT_PAGE    0x01            /* Fixed offset, auto-genned */
  121. X#define PD_DT_V4BYTE    0x02            /* Short root descriptor */
  122. X#define    PD_DT_V8BYTE    0x03            /* Long root descriptor */
  123. X
  124. X/* This is needed for identification of bogus systems that test positive
  125. X   for MMUs. */
  126. X
  127. X#define BOGUSMMU    0xffffffffL
  128. X
  129. X/* Here's the MMU support stuff. */
  130. X
  131. X#define ROMROUND    0x00020000L    /* ROM/Main level at 128K grain */
  132. X#define SMALLROMSIZE    0x00040000L
  133. X#define BIGROMSIZE    0x00080000L
  134. X#define DEVROUND    0x00004000L    /* Device level at 16K grain */
  135. X#define STKROUND    0x00000400L    /* Stack level at 1K grain */
  136. X#define TABROUND    0x00000400L    /* Table alignment matches page size */
  137. X#define PAGESIZE    0x00020000L
  138. X#define MAINTABSIZE    (128L * sizeof(ULONG))
  139. X#define SUBTABSIZE    (8L * sizeof(ULONG))
  140. X#define STKTABSIZE    (16L * sizeof(ULONG))
  141. X
  142. X/* Magic ROM numbers */
  143. X
  144. X#define MAGIC_256    0x11114ef9
  145. X#define MAGIC_512    0x11144ef9
  146. X   
  147. X/* ====================================================================== */
  148. X
  149. X/* Some external system declarations. */
  150. X
  151. Xextern BPTR Lock(), Open();
  152. X
  153. X/* Checking logic */
  154. X
  155. X#define    CK68000        0
  156. X#define CK68010        1
  157. X#define CK68020        2
  158. X#define CK68030        3
  159. X#define CK68040        4
  160. X#define CK68851        5
  161. X#define CK68881        6
  162. X#define CK68882        7
  163. X#define CKFPU        8
  164. X#define CKMMU        9
  165. X#define CKMMUON        10
  166. X#define CKMMUROM    11
  167. X#define CKMMUALIEN    12
  168. X#define CHECKS        13
  169. X
  170. X#define    WARNING    5
  171. X#define READOK    0L
  172. X
  173. X#define SizeOf(x)    ((ULONG)sizeof(x))
  174. X#define min(a,b)    ((a<b)?a:b)
  175. X#define max(a,b)    ((a>b)?a:b)
  176. X
  177. X/* ====================================================================== */
  178. X
  179. X/* From the CONTROL.A module */
  180. X
  181. Xextern void            SetCACR(),
  182. X                 GetCRP(),
  183. X                SetCRP(),
  184. X                SetTC();
  185. X
  186. Xextern ULONG            GetCACR(),
  187. X                *GetVBR(),
  188. X                 GetTC();
  189. X
  190. X/* ====================================================================== */
  191. X
  192. X/* From the IDENTS.A module */
  193. X
  194. Xextern ULONG            GetCPUType(),
  195. X                GetMMUType(),
  196. X                GetFPUType();
  197. X
  198. X/* ====================================================================== */
  199. X
  200. X/* From the OTHER.A module */
  201. X
  202. Xextern void            SetMMUTag(),
  203. X                FlushATC(),
  204. X                SetKeyDelay();
  205. X
  206. Xextern ULONG            KeyCode,
  207. X                KeyCodeSize,
  208. X                BerrCode,
  209. X                BerrCodeSize;
  210. X
  211. X/* ====================================================================== */
  212. X
  213. X/* From the REBOOT.A module. */
  214. X
  215. Xextern void             ROMBoot(),
  216. X                CleanBoot();
  217. X
  218. Xextern ULONG            BootCode,
  219. X                BootCodeSize,
  220. X                ResetCode,
  221. X                ResetCodeSize;
  222. X
  223. X
  224. X/* ====================================================================== */
  225. X
  226. X/* From the EXPDEV.C module. */
  227. X
  228. X/* This structure is device information used by the memory mapping routine. */
  229. X
  230. Xstruct ExpROMData {
  231. X   struct ExpROMData *next;
  232. X   ULONG ROMbase;
  233. X   ULONG ROMsize;
  234. X   ULONG imagebase;
  235. X   ULONG tablebase;
  236. X   char *name;    
  237. X};
  238. X
  239. Xextern LONG                ReadExpDevs();
  240. Xextern struct ExpROMData        *GetExpROM();
  241. Xextern void                FreeExpROM(),
  242. X                    SafeConfigDevs();
  243. X
  244. X/* ====================================================================== */
  245. X
  246. X/* From the MISC.C module. */
  247. X
  248. X/* Patch types */
  249. X
  250. X#define PT_STRING    1
  251. X#define PT_JSR        2
  252. X#define PT_END        3
  253. X#define PT_IGNORE    4
  254. X#define PT_KEYBOARD    5
  255. X
  256. X/* This is a item */
  257. X
  258. Xstruct pitem {
  259. X   UWORD Type;        /* The type of patch to apply */
  260. X   UWORD Pad;        /* Nothing here yet... */
  261. X   ULONG Offset;    /* The offset at which to apply the patch */
  262. X   ULONG Length;    /* The length of the patch item */
  263. X   UWORD *Code;        /* The actual patch item */
  264. X};
  265. X
  266. X/* This is the patch structure. */
  267. X
  268. Xstruct patch {
  269. X   struct patch *next;    /* Next patchlist */
  270. X   struct pitem *list;    /* First item in this patchlist */
  271. X   UWORD Version;    /* Which ROM version */
  272. X   UWORD Revision;    /*   and revision */
  273. X};
  274. X
  275. X/* These are the some patch system variables. */
  276. X
  277. X#define KEYPATCH        0
  278. X
  279. Xextern struct patch         SystemPatch[];
  280. Xextern struct MemChunk         *lastpatch;
  281. X
  282. X/* The actual functions. */
  283. X
  284. Xextern LONG            striequ(),
  285. X                strniequ();
  286. X
  287. Xextern void            MotorOff();
  288. Xextern BYTE            ReadBuf();
  289. Xextern LONG            CheckTDDev();
  290. X
  291. Xextern LONG            AddPatch();
  292. X
  293. X/* ====================================================================== */
  294. X
  295. X/* From the MMU.C module. */
  296. X
  297. Xextern void             Phantom(),
  298. X                SetMMURegs(),
  299. X                FillBasicTable(),
  300. X                FreeMMUTable(),
  301. X                MakeExpTable(),
  302. X                MakeFastStack(),
  303. X                FreeFastStack();
  304. X
  305. X/* ====================================================================== */
  306. X
  307. X/* From the MEMORY.C module. */
  308. X
  309. X/* This section describes the system tag structure, where I stick all the
  310. X   information that I like to keep around.  */
  311. X   
  312. X#define ROM_NOP            0x0000    /* No ROM operation called for */
  313. X#define ROM_FAST        0x0002    /* Normally installed FASTROM image */
  314. X#define ROM_KICK        0x0003    /* Installed as a KICK image */
  315. X#define ROM_FKICK        0x0004    /* A KICK image made into a FAST image */
  316. X/* This was originally the patchtag structure, which looked like a patch.  I 
  317. X   decided that was real kludgy.  I hook the systag onto an invalid page 
  318. X   descriptor which I locate in the physical ROM image, a place that should 
  319. X   always be safe to have an invalid tag structure.  Don't change this without
  320. X   checking in the "030Stuff.a" file -- some of these structure members are
  321. X   used by the reboot code. */
  322. X
  323. Xstruct systag {
  324. X   ULONG         tagsize;    /* Size of this tag */
  325. X   ULONG         progver;    /* The program version */
  326. X   ULONG        *maintable;    /* The main ROM table */
  327. X   ULONG        *romhi;        /* The main ROM image */
  328. X   UWORD         romtype;    /* Type of MMU ROM */
  329. X   UWORD         patches;    /* The number of other patches applied */
  330. X   struct MemChunk     *patchlist;    /* List of installed patches */
  331. X   struct ExpROMData    *devs;        /* Translated device ROMs */
  332. X   ULONG        TC;        /* Precomputed TC used for KICK. */
  333. X   ULONG        CRP[2];        /* Precomputed CRP used for KICK. */
  334. X   UWORD        config;        /* Configuration status. */
  335. X   ULONG        BerrSize;    /* Size of bus error handler. */
  336. X   char            *OldBerr;    /* The old BERR routine. */
  337. X   char            *BerrHandler;    /* My BERR routine. */
  338. X   short        wrapup;        /* Upper address wrap bound. */
  339. X   short        wrapdown;    /* Lower address wrap bound. */
  340. X   ULONG        tablesize;    /* Main table size. */
  341. X   char            *ResetCode;    /* Actual reset routine */
  342. X   ULONG        romsize;    /* Size of ROM image */
  343. X   ULONG        romloc;        /* Where does the fool thing go? */
  344. X   ULONG        romstart;    /* And where do we start it up? */
  345. X   ULONG        *romlo;        /* Secondary ROM image, if needed */
  346. X   char            *sysstack;    /* Physical system stack image */
  347. X   ULONG        sysstksize;    /* System Stack allocated size. */
  348. X   ULONG        ResetSize;    /* Size of the reset code. */
  349. X   char            *OldReset;    /* Old Reset Code */
  350. X};
  351. X
  352. X/* The actual functions */
  353. X
  354. Xextern void             MemCopy(),
  355. X                SetMMURegs(),
  356. X                *AllocAligned(),
  357. X                SnoopSpecial(),
  358. X                FillBasicTable(),
  359. X                FreeSAFEImage();
  360. XULONG *                SizeROM();
  361. Xextern struct systag        *AllocROMImage(),
  362. X                *AllocDISKImage(),
  363. X                *AllocSAFEImage(),
  364. X                *GetSysTag();
  365. Xextern LONG            SmartlyGetRange();
  366. X
  367. X/* ====================================================================== */
  368. X
  369. X/* From the DISKIO.C module. */
  370. X
  371. Xextern struct systag     *AllocKSImage(),
  372. X            *AllocFILEImage(),
  373. X            *AllocDISKImage();
  374. X
  375. X/* ====================================================================== */
  376. X
  377. X/* From the COOLHAND.C module. */
  378. X
  379. Xstruct Window *CoolHand();
  380. X
  381. X/* ====================================================================== */
  382. X
  383. X/* Intermodule globals */
  384. X
  385. Xstruct CfgBlock {
  386. X   ULONG Addr, Size;
  387. X};
  388. X
  389. X#ifdef MAIN_MODULE
  390. Xstruct ExpansionBase *ExpansionBase = NULL;    /* The expansion library */
  391. Xunsigned short LoadErr = 16;
  392. Xstruct CfgBlock Bridge = { 0L, 0L }, A26x0 = { 0L, 0L };
  393. X#else
  394. Xextern struct ExpansionBase *ExpansionBase;
  395. Xextern unsigned short LoadErr, forcewrap;
  396. Xextern struct CfgBlock Bridge, A26x0;
  397. Xextern BOOL allochead,aliens;
  398. Xextern ULONG cpu;
  399. X#endif
  400. X
  401. END_OF_FILE
  402. if test 10417 -ne `wc -c <'SetCPU.h'`; then
  403.     echo shar: \"'SetCPU.h'\" unpacked with wrong size!
  404. fi
  405. # end of 'SetCPU.h'
  406. fi
  407. if test -f 'coolhand.c' -a "${1}" != "-c" ; then 
  408.   echo shar: Will not clobber existing file \"'coolhand.c'\"
  409. else
  410. echo shar: Extracting \"'coolhand.c'\" \(7518 characters\)
  411. sed "s/^X//" >'coolhand.c' <<'END_OF_FILE'
  412. X/*
  413. X    SetCPU V1.60
  414. X    by Dave Haynie, April 13, 1990
  415. X    Released to the Public Domain
  416. X
  417. X    COOLHAND MODULE
  418. X
  419. X    This module contains the code used to display a cool looking 
  420. X    KickStart prompt hand on the screen.
  421. X*/
  422. X
  423. X#include "setcpu.h"
  424. X
  425. X/* ====================================================================== */
  426. X
  427. X/* This is the KickStart hand design as in the A1000.  Only, Intuition makes
  428. X   it considerably easier to build than they way the Kernel ROM does it. */
  429. X   
  430. X/* Define the vectors.  The hand is a drawing composed of a series of line
  431. X   vectors.  Intuition provides a handy structure, called a boarder, that'll
  432. X   render this whole mess with a single function call. */
  433. X
  434. Xstatic WORD vect1[] = {  0,  0, 23,  0, 23, 22, 78, 22, 78,  0, 90,  0,101, 11,
  435. X                       101, 83, 92, 83, 92, 45, 29, 45, 27, 43, 18, 43, 17, 45,
  436. X                        10, 45, 10, 54,  0, 61,  0,  0 };
  437. Xstatic WORD vect2[] = {  0,  0,  0,-62, 93,-62,105,-50,105, 23, 53, 23, 53, 28,
  438. X                        49, 36, 45, 41, 41, 44, 35, 53, 27, 57, 27, 68,-23, 68,
  439. X                       -23, 37,-24, 37,-24,  9,-20,  3,-13, -3,-12, -7, -8,-14,
  440. X                        -3,-17,  0,-18,  0,-18, -3,-16, -7,-14,-11, -7,-12, -3,
  441. X                       -19,  3,-23,  9,-23, 36,-22, 37,-22, 67,  7, 67,  7, 46,
  442. X                        15, 46, 19, 44, 19, 23, 17, 20, 17, 10, 32, -3, 32,-15,
  443. X                        29,-17, 26,-17, 29,-14, 29, -7, 28, -6, 21, -6, 18, -9,
  444. X                         9, -2, -3,  4,-15, 13,-15, 12, -3,  3, -7,  2,-10, -1,
  445. X                        -7,  1, -3,  2,  0,  0 };
  446. Xstatic WORD vect3[] = {  0,  0,  2, -7, 10, -6, 11, -3, 11,  4,  4,  4,  0,  0 };
  447. Xstatic WORD vect4[] = {  0,  0,  0,-10, 15,-23, 15,-35, 74,-35, 74,  2,  1,  2,
  448. X                         0, -2 };
  449. Xstatic WORD vect5[] = {  0,  0, 51,  0, 51, 21,  0, 21,  0,  0 };
  450. Xstatic WORD vect6[] = {  0,  0, 11,  0, 11, 14,  0, 14,  0,  0 };
  451. Xstatic WORD vect7[] = {  0,  0,  7,  0,  7, 12,  0, 12,  0,  0 };
  452. Xstatic WORD vect8[] = {  0,  0,  3,  0,  3,  2,  0,  6,  0,  0 };
  453. Xstatic WORD vect9[] = {  0,  0,  0,-20,  7,-20, 12,-25, 12,-34, 16,-32, 24,-32,
  454. X                        24,-30, 28,-25, 32,-25, 32,-23, 26,-14, 18,-11, 18,  0,
  455. X                         0,  0 };
  456. Xstatic WORD vect10[] = { 0,  0,  0,  5,  5,  2,  0,  0 };
  457. Xstatic WORD vect11[] = { 0,  0, -4,  2, -4, -3, 17, -3,  7,  7,  6,  7,  8,  5,
  458. X                         3,  0,  0,  0 };
  459. X
  460. Xstatic WORD vect12[] = { 0,  0,  7,  0,  7,  5,  3, 13,  0, 17, -5, 18, -8, 18,
  461. X                       -11, 14,-11, 11,  0,  0 };
  462. X
  463. Xstatic WORD vect13[] = { 0,  0,  0,  3,  2,  6,  2,  6,  8,  5,  9,  2,  5, -1,
  464. X                         0,  0 };
  465. Xstatic WORD vect14[] = { 0,  0,  8,  2, 10, -1,  6, -5,  3, -5,  0, -3,  0,  0 };
  466. Xstatic WORD vect15[] = { 0,  0, 11, 11, 11, 83 };
  467. X
  468. Xstatic struct Border HandLines[] = {
  469. X   { 105, 51,1,0,JAM1,18, &vect1[0], &HandLines[1] },
  470. X   { 103,112,1,0,JAM1,59, &vect2[0], &HandLines[2] },
  471. X   { 120,101,1,0,JAM1, 7, &vect3[0], &HandLines[3] },
  472. X   { 121,132,1,0,JAM1, 8, &vect4[0], &HandLines[4] },
  473. X   { 130, 51,1,0,JAM1, 5, &vect5[0], &HandLines[5] },
  474. X   { 166, 54,1,0,JAM1, 5, &vect6[0], &HandLines[6] },
  475. X   { 168, 55,1,0,JAM1, 5, &vect7[0], &HandLines[7] },
  476. X   { 117, 97,1,0,JAM1, 5, &vect8[0], &HandLines[8] },
  477. X   { 111,179,1,0,JAM1,15, &vect9[0], &HandLines[9] },
  478. X   { 123,135,1,0,JAM1, 4,&vect10[0],&HandLines[10] },
  479. X   { 127,138,1,0,JAM1, 9,&vect11[0],&HandLines[11] },
  480. X   { 148,135,1,0,JAM1,10,&vect12[0],&HandLines[12] },
  481. X   { 138,146,1,0,JAM1, 8,&vect13[0],&HandLines[13] },
  482. X   { 124,144,1,0,JAM1, 7,&vect14[0],&HandLines[14] },   
  483. X   { 196, 51,1,0,JAM1, 3,&vect15[0],NULL },
  484. X};
  485. X
  486. X/* This is a list of area fills to perform; the first number is the "A" pen
  487. X   to set, the next two numbers are the screen position to start filling
  488. X   from. */
  489. X
  490. Xstatic WORD FillList[][3] = {
  491. X   { 2, 107,109 }, { 3, 132, 71 }, { 2, 169, 66 }, { 1, 104, 51 },
  492. X   { 1, 129, 51 }, { 1, 167, 55 }, { 1, 176, 67 }, { 1, 182, 55 },
  493. X   { 1, 196,134 }, { 1, 145,136 }, { 1, 116, 97 }
  494. X};
  495. X
  496. X#define FILLCNT    11
  497. X
  498. X/* Finally, I've got a few images to render, which I do using the standard
  499. X   Intuition Image structures. */
  500. X
  501. XUWORD image0[] = {    /* AMIGA */
  502. X   0x1f9f,0xfe3f,0xff77,0xfe7c, 0x070c,0xef8f,0x1e71,0xdc30,
  503. X   0x07f8,0xe7ce,0x1cf3,0x1fe0, 0x0731,0xf3ce,0x1df6,0x1cc0,
  504. X   0x0760,0x03dc,0x3ffc,0x1d80, 0x07c0,0x879c,0x3f78,0x1f00,
  505. X   0x0780,0xcf78,0x7e78,0x1e00, 0x0700,0xfeff,0xfc7c,0x1c00,
  506. X   0x1001,0x8220,0x4050,0x0004, 0x0404,0x8889,0x1210,0x5010,
  507. X   0x0408,0x2448,0x1090,0x1020, 0x0410,0x1042,0x0510,0x1040,
  508. X   0x0420,0x0050,0x2690,0x1080, 0x0440,0x0484,0x0900,0x1100,
  509. X   0x0480,0x4960,0x4208,0x1200, 0x0500,0x0683,0x8404,0x1400,
  510. X};
  511. X
  512. XUWORD image1[] = {    /* Kick */
  513. X   0xc71f,0x1e63,0x8000, 0x6631,0x8c63,0x0000, 0x3e01,0x8c33,0x0000, 
  514. X   0x6631,0x8c1f,0x0000, 0xc61f,0x0e33,0x0000, 0x0600,0x0063,0x0000,
  515. X   0x0700,0x0c63,0x8000
  516. X};
  517. X
  518. XUWORD image2[] = {    /* Start */
  519. X   0x703c,0xdc38,0x3e00, 0x9818,0x664c,0x6000, 0x1998,0x780c,0x3c00,
  520. X   0x19b8,0x600c,0x0600, 0x7cdc,0x3c3e,0x7c00, 0x1800,0x000c,0x0000,
  521. X   0x1000,0x0008,0x0000
  522. X};
  523. X
  524. Xstruct Image NameImage[] = {
  525. X   { 126,122,64,8,2,&image0[0],3,0,&NameImage[1] },
  526. X   { 144,112,48,7,1,&image1[0],2,0,&NameImage[2] },
  527. X   { 140,102,48,7,1,&image2[0],2,0,NULL }   
  528. X};
  529. X
  530. X/* Here's the color scheme. */
  531. X
  532. Xstatic WORD coolColor[] = { 0x0fff,0x0000,0x077c,0x0bbb };
  533. X
  534. X/* ====================================================================== */
  535. X
  536. X/* This section contains data for the mechanics of the CoolHand. */
  537. X
  538. Xstatic struct NewScreen newScreen = {
  539. X   0,0,320,200,2,0,1,0,CUSTOMSCREEN,NULL,NULL,NULL,NULL
  540. X};
  541. X
  542. Xstatic struct NewWindow newWindow = {
  543. X   0,0,320,200,2,0,0,BORDERLESS|ACTIVATE,NULL,NULL,NULL,NULL,NULL,0,0,0,0,
  544. X   CUSTOMSCREEN
  545. X};
  546. X
  547. Xstatic struct Screen    *coolScreen;
  548. Xstatic struct Window    *coolWindow, *coolShade;
  549. X
  550. Xstruct GfxBase        *GfxBase;
  551. Xstruct IntuitionBase    *IntuitionBase;
  552. X
  553. X/* ====================================================================== */
  554. X
  555. X/* This is the main section.  Since I consider the CoolHand prompt the end
  556. X   of this life and the beginning of the next, I'm not going to worry about
  557. X   freeing stuff up. */
  558. X   
  559. Xstruct Window *CoolHand() {
  560. X   struct RastPort *rp;
  561. X   struct ViewPort *vp;
  562. X   struct Image *image;
  563. X   LONG size;
  564. X   UWORD i,*bits,*pointer;
  565. X   BOOL ok = TRUE;
  566. X
  567. X   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L);
  568. X   IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L);
  569. X   if (!GfxBase || !IntuitionBase) return;
  570. X   if (!(coolScreen = OpenScreen(&newScreen))) return;
  571. X   ShowTitle(coolScreen,0L);
  572. X   LoadRGB4(vp = &coolScreen->ViewPort,&coolColor[0],4L);
  573. X   newWindow.Screen = coolScreen;
  574. X   pointer = (UWORD *)AllocMem(64L,MEMF_CHIP|MEMF_CLEAR);
  575. X   if (!(coolShade = OpenWindow(&newWindow))) return;
  576. X   if (!(coolWindow = OpenWindow(&newWindow))) return;
  577. X   WindowToFront(coolShade);
  578. X   SetPointer(coolWindow,pointer,2L,2L,0L,0L);
  579. X   Delay(25L);
  580. X   DrawBorder(rp = coolWindow->RPort,&HandLines[0],0L,0L);
  581. X
  582. X   SetOPen(rp,1L);
  583. X   for (i = 0; i < FILLCNT; ++i) {
  584. X      SetAPen(rp,(long)FillList[i][0]);
  585. X      Flood(rp,0L,(long)FillList[i][1],(long)FillList[i][2]);
  586. X   }
  587. X   for (image = &NameImage[0]; image; image = image->NextImage) {
  588. X      size = (LONG) (((image->Width+15)/16)*image->Height)*2*image->Depth;
  589. X      movmem((char *)image->ImageData,
  590. X             (char *)(bits = (UWORD *)AllocMem(size,MEMF_CHIP)),
  591. X             (int)size);
  592. X      image->ImageData = bits;
  593. X   }
  594. X   DrawImage(rp,&NameImage[0],0L,0L);
  595. X   CloseWindow(coolShade);
  596. X   return coolWindow;
  597. X}
  598. END_OF_FILE
  599. if test 7518 -ne `wc -c <'coolhand.c'`; then
  600.     echo shar: \"'coolhand.c'\" unpacked with wrong size!
  601. fi
  602. # end of 'coolhand.c'
  603. fi
  604. if test -f 'memory.c' -a "${1}" != "-c" ; then 
  605.   echo shar: Will not clobber existing file \"'memory.c'\"
  606. else
  607. echo shar: Extracting \"'memory.c'\" \(11245 characters\)
  608. sed "s/^X//" >'memory.c' <<'END_OF_FILE'
  609. X/*
  610. X    SetCPU V1.60
  611. X    by Dave Haynie, April 13, 1990
  612. X    Released to the Public Domain
  613. X
  614. X    MEMORY.C MODULE
  615. X
  616. X    This module is responsible for ROM image allocation, MMU table
  617. X    allocation and creation, and other functions based on memory.
  618. X*/
  619. X
  620. X#include "setcpu.h"
  621. X
  622. X/* ====================================================================== */
  623. X
  624. X/* Local data types */
  625. X
  626. Xstruct range {
  627. X   ULONG first;
  628. X   ULONG last;
  629. X};
  630. X
  631. X/* ====================================================================== */
  632. X
  633. X/* This function copies from the source to the destination, by longword, with
  634. X   BYTE length "length". */
  635. X
  636. Xvoid MemCopy(src,des,len)
  637. XULONG *src, *des;
  638. XULONG len;
  639. X{
  640. X   len = (len + 3)>>2;
  641. X   while (len--) *des++ = *src++;
  642. X}
  643. X
  644. X/* ====================================================================== */
  645. X
  646. X/* This section contains the memory allocation code.  There are two
  647. X   problems here.  First of all, we'd like to use 32 bit FAST memory if 
  648. X   at all possible.  Next, block translation and page tables must be on at
  649. X   least a page sized boundary, if not a block boundary.  */
  650. X   
  651. X/* This routine finds the memory block for me to use in AllocAligned().
  652. X   It takes into account either A2620 or A2630 systems, where I can snoop 
  653. X   out the memory for that particular board, knowing it's the fastest.  I
  654. X   can adjust for 1.4's automatic memory merging in this case too, to be
  655. X   sure I have 32 bit RAM.  If I don't have one of my boards, I'll return 
  656. X   a pointer to the first non-$C00000 memory list marked as FAST. */
  657. X
  658. Xstatic struct range SRange = { 0L, 0L };
  659. Xstatic ULONG MaxMem = 0;
  660. X
  661. XLONG SmartlyGetRange() {
  662. X   struct ExecBase *eb = *((struct ExecBase **)4L);
  663. X   register struct MemHeader *mem;
  664. X
  665. X   /* First try for either A2620 or A2630 */
  666. X   
  667. X   if (A26x0.Addr && A26x0.Size) {
  668. X      SRange.first = A26x0.Addr;
  669. X      SRange.last = A26x0.Size + SRange.first;
  670. X   } 
  671. X
  672. X   /* For another critters, but we go here to find MaxMem, even
  673. X      if we know it's an A26x0. */
  674. X
  675. X   for (mem = (struct MemHeader *)eb->MemList.lh_Head; mem->mh_Node.ln_Succ;
  676. X        mem = (struct MemHeader *)mem->mh_Node.ln_Succ) {
  677. X      if ((ULONG)(mem->mh_Upper) > MaxMem) MaxMem = (ULONG)mem->mh_Upper;
  678. X      if (mem->mh_Attributes & MEMF_CHIP) continue;
  679. X      if (((ULONG)mem >= 0xc00000 && (ULONG)mem <= 0xc80000)) continue;
  680. X      if (!SRange.first) {
  681. X         SRange.first = (ULONG)mem->mh_Lower;
  682. X         SRange.last = (ULONG)mem->mh_Upper;
  683. X      }
  684. X   }
  685. X   if (SRange.first) 
  686. X      return TRUE;
  687. X   return FALSE;
  688. X}
  689. X
  690. X/* This routine allocates such an aligned block of memory from a specified 
  691. X   memory list. */
  692. X   
  693. Xvoid *AllocAligned(size,bound)
  694. Xregister ULONG size;
  695. Xregister ULONG bound;
  696. X{
  697. X   register ULONG target;
  698. X   void *mem = NULL;
  699. X
  700. X   Forbid();
  701. X   if (!allochead) {
  702. X      target = (SRange.last-size) & ~(bound-1);
  703. X      while (target > SRange.first && !(mem = AllocAbs(size,target)))
  704. X         target -= bound;
  705. X      SRange.last = (ULONG)mem;
  706. X   } else {
  707. X      target = (SRange.first+size+bound-1) & ~(bound-1);
  708. X      while (target < SRange.last && !(mem = AllocAbs(size,target)))
  709. X         target += bound;
  710. X      SRange.first = (ULONG)mem+size;
  711. X   }
  712. X   Permit();
  713. X   return mem;
  714. X}
  715. X
  716. X/* This routine finds the memory wrap and appropriate MMU table size for
  717. X   the given configuration. It requires the value of MaxMem to have been
  718. X   already calculated. */
  719. X   
  720. Xvoid FindWrap(tag)
  721. Xstruct systag *tag;
  722. X{
  723. X   ULONG test;
  724. X     
  725. X   if (forcewrap == -1) {
  726. X      tag->wrapdown = 0;
  727. X      for (test = MaxMem; !(test & 0x80000000) && tag->wrapdown < 8; test <<= 1)
  728. X         tag->wrapdown++;
  729. X   } else
  730. X      tag->wrapdown = forcewrap;
  731. X   tag->tablesize = (128 << (8 - tag->wrapdown)) * sizeof(ULONG);
  732. X}
  733. X
  734. X/* This routine computes the ROM size from the magic tag values. */
  735. X
  736. XULONG CalcROMSize(tagval)
  737. XULONG tagval;
  738. X{
  739. X   if (tagval == MAGIC_256) return SMALLROMSIZE;
  740. X   if (tagval == MAGIC_512) return BIGROMSIZE;
  741. X   return 0L;
  742. X}
  743. X
  744. X/* This function sizes the ROM based on its base value and correctly splits 
  745. X a base address between possible ROM halves. This routine uses the Commodore
  746. X   ROM file format, which is like this:
  747. X
  748. X    0:    00000000
  749. X    4:    size
  750. X    8:    start of ROM
  751. X
  752. X   The ROM, in any case, begins with either "$11114ef9", for 256L ROMs, or
  753. X   "$11144ef9", for 512K ROMs.  The next longword can be used to figure out
  754. X   where the ROM actually goes, in memory. */
  755. X
  756. XULONG *SizeROM(tag,base,getram)
  757. Xstruct systag *tag;
  758. XULONG *base, getram;
  759. X{
  760. X   ULONG *rom = NULL;
  761. X
  762. X   if (!(tag->romsize = CalcROMSize(base[0]))) return NULL;
  763. X
  764. X   if (getram) 
  765. X      if (!(rom = (ULONG *)AllocAligned(tag->romsize,ROMROUND))) return NULL;
  766. X
  767. X   if (tag->romsize == SMALLROMSIZE) {
  768. X      tag->romstart = base[1];
  769. X      tag->romloc = base[1] & 0xfffc0000;
  770. X      tag->romlo = 0L;
  771. X      tag->romhi = rom;
  772. X   } else {
  773. X      tag->romstart = base[1];
  774. X      tag->romloc = base[1] & 0xfff80000;
  775. X      tag->romlo = rom;
  776. X      tag->romhi = (ULONG *)((ULONG)rom + SMALLROMSIZE);
  777. X   }
  778. X   return rom;
  779. X}
  780. X
  781. X/* ====================================================================== */
  782. X
  783. X/* This section contains routines that manage different ROM image types. */
  784. X
  785. X/* This function gets an aligned ROM image copied from system ROM. */
  786. X
  787. Xstruct systag *AllocROMImage(type)
  788. XUWORD type;
  789. X{
  790. X   struct systag *tag = NULL, *oldtag = NULL;
  791. X   ULONG *rom = NULL, *table = NULL, *base;
  792. X   
  793. X  /* Let's make the allocations.  I allocate the ROM first, then the table,
  794. X     then the tag; since we're coming from the end of memory, this should
  795. X     result in the least fragging. */
  796. X
  797. X   SmartlyGetRange();
  798. X   if (!(tag = AllocAligned(SizeOf(struct systag),8L))) goto fail;
  799. X   if (oldtag = GetSysTag())
  800. X      base = (ULONG *)oldtag->romloc;
  801. X   else {
  802. X      if (*(base = (ULONG *)0x00f80000) != MAGIC_512)
  803. X         base = (ULONG *)0x00fc0000;
  804. X   }
  805. X   rom = SizeROM(tag,base,TRUE);
  806. X   FindWrap(tag);
  807. X   if (!(table = AllocAligned(tag->tablesize+4,TABROUND))) goto fail;
  808. X   tag->maintable = table;
  809. X   tag->romtype = type;
  810. X   MemCopy(tag->romloc,rom,tag->romsize);
  811. X   FillBasicTable(tag,FALSE);
  812. X   return tag;
  813. X
  814. Xfail:
  815. X   if (rom)   FreeMem(rom,tag->romsize);
  816. X   if (table) FreeMem(table,tag->tablesize+4);
  817. X   if (tag)   FreeMem(tag,SizeOf(struct systag));
  818. X   return NULL;
  819. X}
  820. X
  821. X/* This function gets an aligned, reset-safe image in either $00C00000 or 
  822. X   CHIP memory, copies the ROM code from the passed temporary image, and 
  823. X   then sets up it's MMU table such that the memory used for the safe image
  824. X   will be missed by the Amiga's memory-sizing logic on reboot. */
  825. X
  826. Xstruct systag *AllocSAFEImage(temp)
  827. Xstruct systag *temp;
  828. X{
  829. X   struct ExecBase *eb = *((struct ExecBase **)4L);
  830. X   struct MemHeader *safe, *safeC000 = NULL, *safeCHIP = NULL, *tmem;
  831. X   struct systag *tag;
  832. X   ULONG upper, base, *table;
  833. X
  834. X   for (safe = (struct MemHeader *)eb->MemList.lh_Head; safe->mh_Node.ln_Succ; 
  835. X        safe = (struct MemHeader *)safe->mh_Node.ln_Succ) {
  836. X      tmem = (struct MemHeader *)safe;
  837. X      if ((ULONG)(tmem->mh_Upper) > MaxMem) MaxMem = (ULONG)tmem->mh_Upper;      
  838. X      if (tmem->mh_Attributes & MEMF_CHIP) {
  839. X         if (!safeCHIP || safeCHIP->mh_Upper < tmem->mh_Upper)
  840. X            safeCHIP = tmem;
  841. X      } else if ((ULONG)safe >= 0xc00000 && (ULONG)safe <= 0xc80000) {
  842. X         if (!safeC000 || safeC000->mh_Upper < tmem->mh_Upper)
  843. X            safeC000 = tmem;
  844. X      }
  845. X   }
  846. X
  847. X  /* Will it fit?  You need at least 1 meg of memory. */
  848. X
  849. X   if (!safeC000 && safeCHIP->mh_Upper < 0x080000L) return NULL;
  850. X
  851. X  /* Now, where should it go. */
  852. X
  853. X   if (safeC000)
  854. X      upper = ((ULONG)safeC000->mh_Upper+ROMROUND-1L) & ~(ROMROUND-1L);
  855. X   else if (safeCHIP)
  856. X      upper = ((ULONG)safeCHIP->mh_Upper+ROMROUND-1L) & ~(ROMROUND-1L);
  857. X
  858. X   FindWrap(temp);
  859. X   table = (ULONG *)(base = upper-ROMROUND);
  860. X   tag = (struct systag *)(base = (base + temp->tablesize + 36L) & ~7L);
  861. X   *tag = *temp;
  862. X   tag->maintable = table;
  863. X   
  864. X   if (temp->romlo) {
  865. X      tag->romlo = (ULONG *)(upper - SMALLROMSIZE - ROMROUND);
  866. X      if (safeC000) {
  867. X         upper = ((ULONG)safeCHIP->mh_Upper+ROMROUND-1L) & ~(ROMROUND-1L);
  868. X         tag->romhi = (ULONG *)(upper - SMALLROMSIZE);
  869. X      } else
  870. X         tag->romhi = (ULONG *)(upper - SMALLROMSIZE*2 - ROMROUND);
  871. X   } else {
  872. X      tag->romhi = (ULONG *)(upper - temp->romsize - ROMROUND);
  873. X      tag->romlo = 0L;
  874. X   }
  875. X
  876. X  /* Other tag initializations. */
  877. X
  878. X   tag->romtype = ROM_KICK;
  879. X   FillBasicTable(tag,TRUE);
  880. X
  881. X   base = (base + SizeOf(struct systag) + 32L) & ~7L;
  882. X
  883. X   tag->BerrHandler = (char *)(base = (base + SizeOf(struct systag)+32L) & ~7L);
  884. X   tag->BerrSize = (BerrCodeSize + 4) & ~3L;
  885. X
  886. X   if (tag->romlo) MemCopy(temp->romlo,tag->romlo,SMALLROMSIZE);
  887. X   MemCopy(temp->romhi,tag->romhi,SMALLROMSIZE);
  888. X
  889. X   tag->ResetCode = (char *)(base = (base + BerrCodeSize + 32L) & ~7L);
  890. X   tag->ResetSize = BerrCodeSize;
  891. X   MemCopy(BootCode,tag->ResetCode,BootCodeSize);
  892. X
  893. X   return tag;
  894. X}
  895. X
  896. X/* This function returns memory to the system, automatically setting the
  897. X   appropriate memory flags. */
  898. X
  899. Xvoid ReturnMem(size,mem)
  900. XULONG size;
  901. XULONG mem;
  902. X{
  903. X   if (mem < 0x00200000)
  904. X      AddMemList(size,MEMF_CHIP|MEMF_PUBLIC,-15L,(char *)mem,NULL);
  905. X   else if (mem >= 0x00c00000 && mem < 0x00c80000)
  906. X      AddMemList(size,MEMF_FAST|MEMF_PUBLIC,-15L,(char *)mem,NULL);
  907. X   else
  908. X      AddMemList(size,MEMF_FAST|MEMF_PUBLIC,0L,(char *)mem,NULL);
  909. X}
  910. X
  911. X/* This function can be used after rebooting to remove the specially allocated
  912. X   SAFE image.  This is normally used after copying the safe image into a 
  913. X   standard FASTROM image and adjusting the MMU accordingly.  The SAFE RAM
  914. X   at this point isn't in any memory list, so we aren't really freeing it,
  915. X   just linking it into a list. */
  916. X
  917. Xvoid FreeSAFEImage(kick)
  918. Xstruct systag *kick;
  919. X{
  920. X   if (kick->romlo == 0 || (ULONG)kick->romhi+SMALLROMSIZE == (ULONG)kick->romlo)
  921. X      ReturnMem(ROMROUND+kick->romsize,kick->romhi);
  922. X   else {
  923. X      ReturnMem(ROMROUND+SMALLROMSIZE,kick->romlo);
  924. X      ReturnMem(SMALLROMSIZE,kick->romhi);
  925. X   }
  926. X}
  927. X
  928. X/* ====================================================================== */
  929. X
  930. X/* This routine gets the system tag from the patched system, if it's
  931. X   there.  This tag is stored in an invalid table entry that's within the
  932. X   physical ROM image.  If the MMU isn't on, there's no system tag, by
  933. X   definition.  This has been enhanced to perform a sanity check on the
  934. X   tag encountered -- the systag contains a pointer to the table, this
  935. X   can be checked. */
  936. X   
  937. Xstruct systag *GetSysTag() {
  938. X   struct systag *maybetag;
  939. X   ULONG i, myCRP[2], *table = NULL,size;
  940. X   APTR oldTrap;
  941. X   struct Task *task;
  942. X
  943. X   if (cpu == 68040 || !(GetTC() & TC_ENB) || aliens) return NULL;
  944. X
  945. X   GetCRP(myCRP);
  946. X   table = (ULONG *)myCRP[1];
  947. X
  948. X  /* In case the MMU is alien and has some of this memory read protected... */
  949. X   task = FindTask(0L);
  950. X   oldTrap = task->tc_TrapCode;
  951. X   task->tc_TrapCode = (APTR)BerrCode;
  952. X
  953. X  /* The tag is now in an easier-to-locate place. This isn't SetCPU V1.5
  954. X     compatible; SetCPU V1.5 FASTROM will appear alien to SetCPU V1.6. But
  955. X     this is much better for modern systems and modern software. */
  956. X   size = (myCRP[0]>>16)+1;
  957. X   maybetag = (struct systag *)IV_ADDR(table[size]);
  958. X   if (!maybetag || maybetag->maintable != table || maybetag->tablesize != size<<2) 
  959. X      maybetag = NULL;
  960. X
  961. X  /* Restore the trap vector */
  962. X   task->tc_TrapCode = oldTrap;
  963. X   return maybetag;
  964. X}
  965. X
  966. END_OF_FILE
  967. if test 11245 -ne `wc -c <'memory.c'`; then
  968.     echo shar: \"'memory.c'\" unpacked with wrong size!
  969. fi
  970. # end of 'memory.c'
  971. fi
  972. if test -f 'mmu.c' -a "${1}" != "-c" ; then 
  973.   echo shar: Will not clobber existing file \"'mmu.c'\"
  974. else
  975. echo shar: Extracting \"'mmu.c'\" \(8963 characters\)
  976. sed "s/^X//" >'mmu.c' <<'END_OF_FILE'
  977. X/*
  978. X    SetCPU V1.60
  979. X    by Dave Haynie, April 13, 1990
  980. X    Released to the Public Domain
  981. X
  982. X    MMU.C MODULE
  983. X
  984. X    This module is responsible for some of the MMU table creation
  985. X        functions.
  986. X*/
  987. X
  988. X#include "setcpu.h"
  989. X
  990. X
  991. X/* ====================================================================== */
  992. X
  993. X/* This function maps the phantom area for a given memory location. */
  994. X
  995. Xvoid Phantom(tag,loc)
  996. Xstruct systag *tag;
  997. XULONG loc;
  998. X{
  999. X   ULONG xindex = loc/ROMROUND;
  1000. X
  1001. X   if (xindex < 60)
  1002. X      tag->maintable[xindex] = PD_ADDR(0x00800000)|PD_DT_PAGE;
  1003. X   else
  1004. X      tag->maintable[xindex] = PD_ADDR(0x00ce0000)|PD_DT_PAGE;
  1005. X}
  1006. X
  1007. X
  1008. X/* This table contains a list of the blocks of memory that should be 
  1009. X   cache-inhibited. */
  1010. X
  1011. Xstatic ULONG InTable[] = { 0x00000000,0x00200000,0x00b00000,0x00f00000,0L,0L };
  1012. X   
  1013. X
  1014. X/* This function fills the basic MMU table and other standard tag itemd from 
  1015. X   an allocated image.  Some tables may need additional information in the 
  1016. X   table.  The basic table consists of one table level and uses direct page 
  1017. X   translation on a grain of 128K per entry.  Everything's directly mapped 
  1018. X   except for the last two entries, which are for the $FC0000-$FFFFFF area. */
  1019. X
  1020. Xvoid FillBasicTable(tag,phantoms)
  1021. Xstruct systag *tag;
  1022. XLONG phantoms;
  1023. X{
  1024. X   register ULONG i, image, j;
  1025. X   ULONG page,size,loc;
  1026. X    
  1027. X   tag->tagsize = SizeOf(struct systag);
  1028. X   tag->progver = PROGRAM_VERSION;
  1029. X   tag->patches = 0;
  1030. X   tag->patchlist = tag->devs = NULL;
  1031. X   tag->config = 1;
  1032. X   tag->BerrSize = 0L;
  1033. X   tag->OldBerr = tag->BerrHandler = NULL;
  1034. X   tag->sysstack = NULL;
  1035. X   tag->sysstksize = 0;
  1036. X   tag->OldReset = tag->ResetCode = NULL;
  1037. X   tag->ResetSize = 0;
  1038. X
  1039. X  /* Here I make a table that maps everything straight through. */
  1040. X   for (i = 0; i < tag->tablesize/sizeof(ULONG); i++) 
  1041. X      tag->maintable[i] = PD_ADDR(i<<17)|PD_DT_PAGE;
  1042. X   tag->maintable[i] = IV_ADDR(tag)|PD_DT_INVALID;
  1043. X
  1044. X  /* Mark the inhibited pages. */
  1045. X   for (i = 0; InTable[i+1]; i += 2)
  1046. X      for (j = InTable[i]/PAGESIZE; j < InTable[i+1]/PAGESIZE; ++j)
  1047. X         tag->maintable[j] |= PD_CI;
  1048. X
  1049. X  /* Here I map the ROM image to the ROM location. */
  1050. X   image = (ULONG)tag->romlo;
  1051. X   loc = tag->romloc/PAGESIZE;
  1052. X   if (image) {
  1053. X      if (phantoms) Phantom(tag,image);
  1054. X      tag->maintable[loc++] = PD_ADDR(image)|PD_WP|PD_DT_PAGE;
  1055. X      if (phantoms) Phantom(tag,image+PAGESIZE);
  1056. X      tag->maintable[loc++] = PD_ADDR(image+PAGESIZE)|PD_WP|PD_DT_PAGE;
  1057. X   }
  1058. X   image = (ULONG)tag->romhi;
  1059. X   if (phantoms) Phantom(tag,image);
  1060. X   tag->maintable[loc++] = PD_ADDR(image)|PD_WP|PD_DT_PAGE;
  1061. X   if (phantoms) Phantom(tag,image+PAGESIZE);
  1062. X   tag->maintable[loc]   = PD_ADDR(image+PAGESIZE)|PD_WP|PD_DT_PAGE;
  1063. X
  1064. X  /* Here I look for Bridge Cards, which are known to have problems with
  1065. X     the data cache enabled, so I always disable it, reguardless of 
  1066. X     whether caching is actually enabled in the CACR. */
  1067. X
  1068. X   if (Bridge.Addr && Bridge.Size) {
  1069. X      page = Bridge.Addr/PAGESIZE;
  1070. X      size = max((ULONG)Bridge.Size/PAGESIZE,1);
  1071. X      while (size-- && page < tag->tablesize)
  1072. X         if ((tag->maintable[page] & PD_DT_TYPE) == PD_DT_PAGE)
  1073. X            tag->maintable[page++] |= PD_CI;
  1074. X   }     
  1075. X}
  1076. X
  1077. X/* This routine sets up the MMU registers (shadowed in tag fields) in the
  1078. X   standard SetCPU fashion.  The CPU Root Pointer tells the MMU about the 
  1079. X   table I've set up, and all that's left to do is bang the Translation
  1080. X   Control Register to turn the thing on.  Note that the first half of the 
  1081. X   CRP is control data, the second the address of my table.  */
  1082. X   
  1083. Xvoid SetMMURegs(tag)
  1084. Xstruct systag *tag;
  1085. X{
  1086. X   tag->CRP[0] = CRP_LIMIT(tag->tablesize/sizeof(ULONG)-1)|CRP_SG|CRP_DT_V4BYTE;
  1087. X   tag->CRP[1] = (ULONG)(tag->maintable);
  1088. X
  1089. X   tag->TC = TC_PS(0x0a)|TC_IS(tag->wrapup)|
  1090. X             TC_TIA(0x0f-tag->wrapup)|TC_TIB(0x03)|TC_TIC(0x04)|TC_TID(0);
  1091. X}
  1092. X
  1093. X/* ====================================================================== */
  1094. X
  1095. X/* This function frees all MMU tables. */
  1096. X
  1097. Xvoid FreeMMUTable(tag)
  1098. Xstruct systag *tag;
  1099. X{
  1100. X   ULONG i,j, *subtab;
  1101. X
  1102. X   for (i = 0; i < 128; ++i)
  1103. X      if ((tag->maintable[i] & PD_DT_TYPE) == PD_DT_V4BYTE) {
  1104. X         for (subtab = (ULONG *)PD_ADDR(tag->maintable[i]), j = 0; j < 8; ++j)
  1105. X            if ((subtab[j] & PD_DT_TYPE) == PD_DT_V4BYTE)
  1106. X               FreeMem((char *)PD_ADDR(subtab[j]),STKTABSIZE);
  1107. X         FreeMem((char *)subtab,SUBTABSIZE);
  1108. X      }
  1109. X   FreeMem((char *)tag->maintable,tag->tablesize);
  1110. X}
  1111. X
  1112. X/* ====================================================================== */
  1113. X
  1114. X/* This function makes subtables for CardROMFile I/O devices. */
  1115. X
  1116. Xvoid MakeExpTable(tag)
  1117. Xstruct systag *tag;
  1118. X{
  1119. X   ULONG i, *SUBTable, iospace;
  1120. X   struct ExpROMData *er;
  1121. X
  1122. X   while (er = GetExpROM()) {
  1123. X      er->next = tag->devs;
  1124. X      tag->devs = er;
  1125. X
  1126. X      iospace = ((ULONG)er->ROMbase)/ROMROUND;
  1127. X
  1128. X     /* If necessary, modify the table */
  1129. X      if (tag->maintable[iospace] == PD_ADDR(iospace<<17)|PD_DT_PAGE) {
  1130. X         if (SUBTable = AllocAligned(SUBTABSIZE,TABROUND)) {
  1131. X            for (i = 0; i < 8; ++i) 
  1132. X               SUBTable[i] = PD_ADDR((iospace<<17)+(i<<14))|PD_CI|PD_DT_PAGE;
  1133. X            tag->maintable[iospace] = PD_ADDR(SUBTable)|PD_DT_V4BYTE;
  1134. X         }
  1135. X      } else
  1136. X         SUBTable = (ULONG *)PD_ADDR(tag->maintable[iospace]);
  1137. X
  1138. X      if (SUBTable) {
  1139. X         er->imagebase = (ULONG)AllocAligned(er->ROMsize,DEVROUND);
  1140. X         er->tablebase = (ULONG)&SUBTable[0];
  1141. X
  1142. X         MemCopy(er->ROMbase,er->imagebase,er->ROMsize);
  1143. X         iospace = (er->ROMbase - (iospace * ROMROUND))/DEVROUND;
  1144. X         for (i = 0; i < er->ROMsize/DEVROUND; ++i)
  1145. X            SUBTable[iospace+i] = PD_ADDR(er->imagebase+(DEVROUND*i))|PD_CI|PD_DT_PAGE;
  1146. X      }
  1147. X   }
  1148. X}
  1149. X
  1150. X/* ====================================================================== */
  1151. X
  1152. X/* This function hunts down the system stack and translates it into a 
  1153. X   block of 32 bit memory if it's found to be located in Chip RAM. Note
  1154. X   that this routine must only be called when the MMU is turned on.  The
  1155. X   current functions used to turn the MMU on make use of the supervisor
  1156. X   stack.  This code must be run in user mode to insure that the supervisor
  1157. X   stack image and the actual stack are the same during the transfer of
  1158. X   control. */
  1159. X
  1160. Xvoid MakeFastStack(tag)
  1161. Xstruct systag *tag;
  1162. X{
  1163. X   struct ExecBase *eb = *((struct ExecBase **)4L);
  1164. X   ULONG i, *SUBTable, *STKTable, tabndx, subndx, stkndx, tmem, base;
  1165. X
  1166. X   base = (((ULONG)eb->SysStkLower)/STKROUND)*STKROUND;
  1167. X
  1168. X   if (base >= 0x00200000L) return;
  1169. X
  1170. X   tag->sysstksize = (((ULONG)eb->SysStkUpper - (ULONG)eb->SysStkLower + 1)/STKROUND)*STKROUND;
  1171. X   tabndx = base/ROMROUND;
  1172. X   tmem = tabndx * ROMROUND;
  1173. X
  1174. X  /* Make the I/O level subtable (level 2).  Most entries are going to be
  1175. X     a straight translation. */
  1176. X
  1177. X   if (!(SUBTable = AllocAligned(SUBTABSIZE,TABROUND)) ||
  1178. X       !(STKTable = AllocAligned(STKTABSIZE,TABROUND))) return;
  1179. X
  1180. X   for (i = 0; i < 8; ++i) 
  1181. X      SUBTable[i] = PD_ADDR(tmem+(i*DEVROUND))|PD_DT_PAGE;
  1182. X   tag->maintable[tabndx] = PD_ADDR(SUBTable)|PD_DT_V4BYTE;
  1183. X
  1184. X  /* Make the Stack level subtable (level 3).  Fill all 16 entries with a
  1185. X     straight translation. */
  1186. X   
  1187. X   subndx = (base - tmem)/DEVROUND;
  1188. X   tmem += subndx * DEVROUND;
  1189. X
  1190. X   for (i = 0; i < 16; ++i)
  1191. X      STKTable[i] = PD_ADDR((tmem)+(i*STKROUND))|PD_DT_PAGE;
  1192. X   SUBTable[subndx] = PD_ADDR(STKTable)|PD_DT_V4BYTE;
  1193. X
  1194. X  /* Now take care of the actual stack translation. */
  1195. X
  1196. X   tag->sysstack = (char *)AllocAligned(tag->sysstksize,STKROUND);
  1197. X   MemCopy(base,tag->sysstack,tag->sysstksize);
  1198. X
  1199. X   stkndx = (base - tmem)/STKROUND;
  1200. X   
  1201. X   for (i = 0; i < tag->sysstksize/STKROUND && i < 16; ++i)
  1202. X      STKTable[i+stkndx] = PD_ADDR(tag->sysstack+(STKROUND*i))|PD_DT_PAGE;
  1203. X   FlushATC();
  1204. X}
  1205. X
  1206. X/* This function removes the fast stack translation. Like the fast stack
  1207. X   creation routine, this must be called with the MMU turned on, in user
  1208. X   mode, so that both stack images can be identical when the switch is
  1209. X   made.  This routine doesn't clean up the MMU tables, it just deals
  1210. X   with the stack image. */
  1211. X
  1212. Xvoid FreeFastStack(tag)
  1213. Xstruct systag *tag;
  1214. X{
  1215. X   struct ExecBase *eb = *((struct ExecBase **)4L);
  1216. X   ULONG *SUBTable, *STKTable, tabndx, subndx, tmem, base;
  1217. X
  1218. X   base = (((ULONG)eb->SysStkLower)/STKROUND)*STKROUND;
  1219. X
  1220. X  /* Find the stack's translation table. */
  1221. X
  1222. X   tabndx = base/ROMROUND;
  1223. X   tmem = tabndx * ROMROUND;
  1224. X   SUBTable = (ULONG *)PD_ADDR(tag->maintable[tabndx]);
  1225. X
  1226. X   subndx = (base - tmem)/DEVROUND;
  1227. X
  1228. X  /* Set things back the way they were. */
  1229. X
  1230. X   Disable();
  1231. X   STKTable = (ULONG *)PD_ADDR(SUBTable[subndx]);
  1232. X   MemCopy(tag->sysstack,base,tag->sysstksize);
  1233. X   SUBTable[subndx] = PD_ADDR(tmem+(subndx*DEVROUND))|PD_DT_PAGE;
  1234. X   FlushATC();
  1235. X   Enable();
  1236. X
  1237. X  /* Get rid of the fast image stuff. */
  1238. X
  1239. X   FreeMem((char *)STKTable,STKTABSIZE);
  1240. X   FreeMem((char *)tag->sysstack,tag->sysstksize);
  1241. X}
  1242. X
  1243. X/* ====================================================================== */
  1244. X
  1245. X/* This routine knows the best way to reset the system, in an attempt to
  1246. X   avoid MMU-based troubles. */
  1247. X
  1248. Xvoid CleverReset()
  1249. X{
  1250. X   geta4();
  1251. X   CleanBoot();
  1252. X}
  1253. END_OF_FILE
  1254. if test 8963 -ne `wc -c <'mmu.c'`; then
  1255.     echo shar: \"'mmu.c'\" unpacked with wrong size!
  1256. fi
  1257. # end of 'mmu.c'
  1258. fi
  1259. echo shar: End of archive 2 \(of 4\).
  1260. cp /dev/null ark2isdone
  1261. MISSING=""
  1262. for I in 1 2 3 4 ; do
  1263.     if test ! -f ark${I}isdone ; then
  1264.     MISSING="${MISSING} ${I}"
  1265.     fi
  1266. done
  1267. if test "${MISSING}" = "" ; then
  1268.     echo You have unpacked all 4 archives.
  1269.     rm -f ark[1-9]isdone
  1270. else
  1271.     echo You still need to unpack the following archives:
  1272.     echo "        " ${MISSING}
  1273. fi
  1274. ##  End of shell archive.
  1275. exit 0
  1276. -- 
  1277. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  1278. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  1279. Post requests for sources, and general discussion to comp.sys.amiga.
  1280.